package com.gary.security.repository.impl;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.GrantedAuthorityImpl;
import org.springframework.security.userdetails.UserDetails;

import com.gary.security.AuthenticationHelper;
import com.gary.security.UserDetailsBuilder;
import com.gary.security.entity.Role;
import com.gary.security.entity.User;

public class UserCallback implements HibernateCallback{
	/** * 角色前缀. */
    private String rolePrefix = "";

    /**
             * 构造方法.
             *
             * @param rolePrefix String
             */
    public UserCallback(String rolePrefix) {
        this.rolePrefix = rolePrefix;
    }

    /**
     * 添加用户.
     *
     * @param session 会话
     * @return Object
     */
    @SuppressWarnings("unchecked")
	public Object doInHibernate(Session session) {
        List<User> users = session.createCriteria(User.class).list();

        List<UserDetails> authUsers = new ArrayList<UserDetails>();

        for (User user : users) {
            GrantedAuthority[] arrayAuths = AuthenticationHelper
                .convertToGrantedAuthority(getAuthsByUser(user));
            authUsers.add(UserDetailsBuilder.createUser(
                    user.getUsername(), user.getPassword(),
                    user.getStatus(), arrayAuths));
        }

        return authUsers;
    }

    /**
     * 通过用户获得授权.
     *
     * @param user User
     * @return List
     */
    private List<GrantedAuthorityImpl> getAuthsByUser(User user) {
        List<GrantedAuthorityImpl> list = new ArrayList<GrantedAuthorityImpl>();

        for (Role role : user.getRoles()) {
            String roleName = this.rolePrefix + role.getName();
            GrantedAuthorityImpl authority = new GrantedAuthorityImpl(roleName);
            list.add(authority);
        }

        return list;
    }
}
